/**
 * @fileoverview Classes for Icodeon SCORM Content Object Communication Data Model
 * @author Icodeon Ltd mailto:sales@icodeon.com
 * @license Apache License 2.0
 * @version 1.0
 */
var icodeon;
if(!icodeon){icodeon = {};}
else if(typeof icodeon != "object"){throw new Error("namepsace icodeon exists");}
if(!icodeon.cocd){icodeon.cocd = {};}
else if(typeof icodeon.cocd != "object"){throw new Error("namepsace icodeon.cocd exists");}

/**
 * Construct an Error subclass for COCD data model exceptions
 * 
 * @class This class represents an instance of CocdError.
 * @extends Error
 * @constructor
 * @return A new instance of CocdError
 */	
icodeon.cocd.CocdError = function(int_ErrorCode, str_Diagnostic){

	/**
	 * Method to call the superclass.
	 */
	Error.call(this, int_ErrorCode + "-" + str_Diagnostic);
	this.message = int_ErrorCode + "-" + str_Diagnostic;
	
	/**
	 * @return A SCORM 2004 error code
	 * @type Number
	 */
	this.getErrorCode = function(){
		return int_ErrorCode;
	}

	this.toString = function(){
		var str_Msg = "Type: icodeon.cocd.CocdError \n";
		str_Msg += "message: " + this.message + "\n";
		return str_Msg;
	};
};

// CocdError properties
icodeon.cocd.CocdError.prototype = new Error();
icodeon.cocd.CocdError.prototype.constructor = icodeon.cocd.CocdError;

/**
 * @extends Object
 * @base Object
 * @class The class represents an instance of the 
 * Content Object Communication Data Model and wraps
 * an IEEE 1484 valid XML instance
 * @constructor
 * @return A new instance of a Cocd
 * @throws icodeon.cocd.CocdError
 */
icodeon.cocd.Cocd = function(){
	
	// imports
	this.x = icodeon.xml;
	this.c = icodeon.cocd;
	
	// static constants
	this.COMMENTS_FROM_LEARNER = "commentsFromLearner";
	this.COMMENTS_FROM_LMS = "commentsFromLMS";
	this.COMPLETION_STATUS = "completionStatus";
	this.CREDIT = "credit";
	this.DATA_MODEL_VERSION = "dataModelVersion";
	this.ENTRY = "entry";
	this.EXIT = "exit";
	this.INTERACTIONS = "interactions";
	this.LAUNCH_DATA = "launchData";
	this.LEARNER_ID = "learnerId";
	this.LEARNER_NAME = "learnerName";
	this.LEARNER_PREFERENCE_DATA = "learnerPreferenceData";
	this.AUDIO_LEVEL = "audioLevel";
	this.LANGUAGE = "language";
	this.DELIVERY_SPEED = "deliverySpeed";
	this.AUDIO_CAPTIONING = "audioCaptioning";
	this.LESSON_STATUS = "lessonStatus";
	this.LOCATION = "location";
	this.MAX_TIME_ALLOWED = "maxTimeAllowed";
	this.MODE = "mode";
	this.OBJECTIVES = "objectives";
	this.SCORE = "score";
	this.SESSION_TIME = "sessionTime";
	this.SUCCESS_STATUS = "successStatus";
	this.TIME_LIMIT_ACTION = "timeLimitAction";
	this.TOTAL_TIME = "totalTime";
	
	this.COMPLETION_STATUS_VALUES = ["unknown"];
	this.CREDIT_VALUES = ["credit"];
	this.DATA_MODEL_VERSION_VALUES = ["1.0"];
	this.ENTRY_VALUES = ["ab_initio"];
	this.EXIT_VALUES = [""];
	this.AUDIO_CAPTIONING_VALUES = ["no_change"];
	this.LESSON_STATUS_VALUES = ["not_attempted"];
	this.MODE_VALUES = ["normal"];
	this.SUCCESS_STATUS_VALUES = ["unknown"];
	this.TIME_LIMIT_ACTION_VALUES = ["continue_no_message"];
	this.TOTAL_TIME_VALUES = ["PT0H0M0S"];

	/**
	 * @final
	 */
	this.EMPTY_STR = "";
	
    this.arr_NameSpaces = new Array();
    this.arr_NameSpaces[""] = "http://ltsc.ieee.org/xsd/1484_11_3";
	
	try{
		var obj_DomDocument = this.x.createDomDocument("cocd",this.arr_NameSpaces[0]);
		this.obj_RootElement = obj_DomDocument.documentElement;
    	this.x.appendChildElement(this.obj_RootElement,this.COMMENTS_FROM_LEARNER);    		
    	this.x.appendChildElement(this.obj_RootElement,this.COMMENTS_FROM_LMS);
    	this.x.appendChildElement(this.obj_RootElement,this.COMPLETION_STATUS, this.COMPLETION_STATUS_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.CREDIT, this.CREDIT_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.DATA_MODEL_VERSION, this.DATA_MODEL_VERSION_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.ENTRY, this.ENTRY_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.EXIT, this.EXIT_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.INTERACTIONS);
    	this.x.appendChildElement(this.obj_RootElement,this.LAUNCH_DATA);
    	this.x.appendChildElement(this.obj_RootElement,this.LEARNER_ID);
    	this.x.appendChildElement(this.obj_RootElement,this.LEARNER_NAME);
    	var obj_Node = this.x.appendChildElement(this.obj_RootElement,this.LEARNER_PREFERENCE_DATA);
    	this.x.appendChildElement(obj_Node,this.AUDIO_LEVEL,"1");
    	this.x.appendChildElement(obj_Node,this.LANGUAGE);
    	this.x.appendChildElement(obj_Node,this.DELIVERY_SPEED,"1");
    	this.x.appendChildElement(obj_Node,this.AUDIO_CAPTIONING,this.AUDIO_CAPTIONING_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.LESSON_STATUS, this.LESSON_STATUS_VALUES[0]);
   		this.x.appendChildElement(this.obj_RootElement,this.LOCATION);
    	this.x.appendChildElement(this.obj_RootElement,this.MAX_TIME_ALLOWED);
    	this.x.appendChildElement(this.obj_RootElement,this.MAX_TIME_ALLOWED);
    	this.x.appendChildElement(this.obj_RootElement,this.MODE, this.MODE_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.OBJECTIVES);
    	this.x.appendChildElement(this.obj_RootElement,this.SCORE);
    	this.x.appendChildElement(this.obj_RootElement,this.SESSION_TIME);
    	this.x.appendChildElement(this.obj_RootElement,this.SUCCESS_STATUS, this.SUCCESS_STATUS_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.TIME_LIMIT_ACTION, this.TIME_LIMIT_ACTION_VALUES[0]);
    	this.x.appendChildElement(this.obj_RootElement,this.TOTAL_TIME, this.TOTAL_TIME_VALUES[0]);
	}
	catch(obj_XmlError){
		throw new this.c.CocdError(102, "COCD initialization failed: " + obj_XmlError.message);
	}
    
   /**
    * Returns an array of nodes using an Xpath expression based on the 
    * cocd root node.
	* @param {String} str_XPath
	* @return An array of Cocd nodes
	* @type Array
	* @throws icodeon.cocd.CocdError
	*/
    this.getNodes = function(str_XPath){

		try{
      	 	var obj_Expr = new this.x.XPathExpression(str_XPath, this.arr_NameSpaces);
       		return obj_Expr.getNodes(obj_Node);
		}
		catch(obj_Error){
			throw new this.c.CocdError(301, "Get failed: " + obj_Error.message);
		}
    };
    
    /**
     * Returns a single leaf node using an Xpath expression based on the 
     * cocd root node.
	 * @param {String} str_XPath
	 * @return Cocd node
	 * @type Node
	 * @throws icodeon.cocd.CocdError
	 */
    this.getNode = function(str_XPath){

		try{
      	 	var obj_Expr = new this.x.XPathExpression(str_XPath, this.arr_NameSpaces);
       		return obj_Expr.getNode(this.obj_RootElement);
		}
		catch(obj_Error){
			throw new this.c.CocdError(301, "Get failed: " + obj_Error.message);
		}
    };
    
    /**
	 * @throws icodeon.cocd.CocdError
	 */
    this.commit = function(){
    };
    
	/*
	 */
	this.serialize = function(){
		var obj_Serializer = new this.x.Serializer();
		return obj_Serializer.serialize(this.obj_RootElement);
	};
    
	/**
	 * Overriden method inherited from Object
	 */
	this.toString = function(){
		var str_Msg = "Type: icodeon.cocd.Cocd";
		return str_Msg;
	};
};
